package org.jeecg.modules.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.MsgResult;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.config.app.WechatUtil;
import org.jeecg.modules.api.announcement.entity.Announcement;
import org.jeecg.modules.api.announcement.service.IAnnouncementService;
import org.jeecg.modules.api.levelexplain.entity.LevelExplain;
import org.jeecg.modules.api.levelexplain.service.ILevelExplainService;
import org.jeecg.modules.api.member.entity.Member;
import org.jeecg.modules.api.member.service.IMemberService;
import org.jeecg.modules.api.order.service.IOrderService;
import org.jeecg.modules.api.recommendrecord.entity.RecommendRecord;
import org.jeecg.modules.api.recommendrecord.service.IRecommendRecordService;
import org.jeecg.modules.api.sourcemember.entity.SourceMember;
import org.jeecg.modules.api.sourcemember.service.ISourceMemberService;
import org.jeecg.modules.api.video.service.IVideoService;
import org.jeecg.modules.app.service.IIndexService;
import org.jeecg.modules.app.service.ITeamService;
import org.jeecg.modules.app.service.IWeChatService;
import org.jeecg.modules.helper.MemberHelp;
import org.jeecg.modules.helper.MessageHelp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
@Slf4j
public class WeChatServiceImpl implements IWeChatService {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private IIndexService indexService;
    @Autowired
    private ILevelExplainService levelExplainService;
    @Autowired
    private IAnnouncementService announcementService;
    @Autowired
    private IVideoService videoService;
    @Autowired
    private ISourceMemberService sourceMemberService;
    @Autowired
    private ITeamService teamService;
    @Autowired
    private IRecommendRecordService recommendRecordService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private MessageHelp messageHelp;
    @Autowired
    private MemberHelp memberHelp;
    @Autowired
    private ISysBaseAPI sysBaseAPI;

    @Override
    public Map<String, Object> getUserInfo(String req) {
        JSONObject jsonObject = JSONObject.parseObject(req);
        String code = jsonObject.getString("code");
        String openid = jsonObject.getString("openid");
        String recommendId = jsonObject.getString("recommendId");
        String userId = jsonObject.getString("userId");
        //是通过app分享出来
        if (StringUtils.isNotEmpty(recommendId) && recommendId.length() >= 32) {
            Member rec = memberService.getBySourceId(recommendId);
            if (rec != null) {
                recommendId = rec.getId().toString();
            } else {
                recommendId = "0";
            }
        }

        if (StringUtils.isBlank(recommendId)) {
            recommendId = "0";
        }
        if (StringUtils.isEmpty(openid)) {
            String result = WechatUtil.requestGetAppId(code); //请求获取appId和session_key
            if (result.contains("errcode")) {
                throw new JeecgBootException("微信请求失败！错误信息 ：" + result);
            }
            Map<String, Object> map = JSONObject.parseObject(result, new TypeReference<Map<String, Object>>() {
            });
            openid = map.get("openid").toString();
            if (StrUtil.isEmpty(openid)) {
                throw new JeecgBootException("微信请求失败！无法获取到openid");
            }
        }

        //设置返回内容
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("isAudit", 1);
        resultMap.put("openid", openid);
        //检查用户
        Member memberDb = memberService.getByOpenid(openid);
        if (memberDb != null) {
            Member rec = memberService.getById(memberDb.getRecommendId());
            if (rec == null && !"0".equals(recommendId) && !recommendId.equals(memberDb.getId().toString())) {//没有绑定推荐人，并且传了推荐人ID
                rec = memberService.getById(recommendId);//查询推荐人信息,绑定关系
                if (rec != null) {
                    memberDb.setRecommendId(rec.getId());
                    log.info("登录绑定推荐人ID：{}", rec.getId());
                    if (StrUtil.isNotEmpty(rec.getFxTeamIds())) {
                        memberDb.setFxTeamIds(rec.getFxTeamIds() + "," + rec.getId());
                    } else {
                        memberDb.setFxTeamIds(String.valueOf(rec.getId()));
                    }
                    memberService.updateById(memberDb);
                }
            }
            memberDb.setRecommend(rec);
            //保存登录信息
            String token = JwtUtil.sign(openid, openid);
            //设置token有效时间12小时
            redisUtil.set(openid, token, 60 * 60 * 12);
            resultMap.put("member", memberDb);
            resultMap.put("token", token);
        } else {

            JSONObject info = new JSONObject();
//            info.put("mobile", phoneNumber);
            info.put("openid", openid);
            info.put("userId", userId);
            info.put("recommendId", recommendId);
            resultMap = this.createUserInfo(info.toJSONString());
        }
        log.info("【会员授权登录返回信息】：{}", resultMap.toString());
        return resultMap;
    }

    @Override
    public void logout(String token) {
        if (StrUtil.isNotEmpty(token)) {
            String openid = JwtUtil.getUsername(token);
            redisUtil.del(openid);
        }
    }

    //创建用户
    public Map<String, Object> createUserInfo(String req) {
        JSONObject jsonObject = JSONObject.parseObject(req);
        String openid = jsonObject.getString("openid");
        String recommendId = jsonObject.getString("recommendId");
        String userId = jsonObject.getString("userId");
        log.info("微信登录请求信息 ===> {}", req);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("isAudit", 1);

        //分销商小程序注册
        Member member = new Member();
        member.setNickname("微信用户");
        member.setOpenid(openid);
        member.setCurrentMonthExtension(BigDecimal.ZERO);
        member.setLastMonthExtension(BigDecimal.ZERO);
        member.setCommission(BigDecimal.ZERO);
        member.setLevel(0);

        if (StringUtils.isNotBlank(userId)) {
            SourceMember sourceMember = sourceMemberService.getById(userId);
            if (sourceMember != null) {
                member.setSourceMemberId(sourceMember.getId());
                member.setNickname(sourceMember.getName());
                member.setAvatar(sourceMember.getAvatar());
                member.setPhone(sourceMember.getPhone());
            }
        }

        Member recommend = null;
        //设置推荐人
        if (StrUtil.isNotEmpty(recommendId)) {
            recommend = memberService.getById(recommendId);
        }
        if (recommend != null) {
            member.setRecommendId(recommend.getId());
            log.info("登录绑定推荐人ID：{}", recommend.getId());
            if (StrUtil.isNotEmpty(recommend.getFxTeamIds())) {
                member.setFxTeamIds(recommend.getFxTeamIds() + "," + recommend.getId());
            } else {
                member.setFxTeamIds(String.valueOf(recommend.getId()));
            }
            member.setRecommend(recommend);
            memberService.save(member);
            //更新推荐人信息
            RecommendRecord recommendRecord = new RecommendRecord();
            recommendRecord.setUserId1(String.valueOf(member.getId()));
            recommendRecord.setUserId2(String.valueOf(recommend.getId()));
            recommendRecordService.save(recommendRecord);
        }else{
            memberService.save(member);
        }
        //保存登录信息
        String token = JwtUtil.sign(openid, openid);
        //设置token有效时间12小时
        redisUtil.set(openid, token, 60 * 60 * 12);
        resultMap.put("openid", openid);
        resultMap.put("token", token);
        resultMap.put("member", member);
        return resultMap;
    }

    public Map<String, Object> bindUserInfo(String req) {
        JSONObject jsonObject = JSONObject.parseObject(req);
        //没有绑定用户，需要先绑定
        String phoneCode = jsonObject.getString("phoneCode");
        if (StrUtil.isEmpty(phoneCode)) {
            throw new JeecgBootException("获取手机号授权code失败");
        }
        String accessToken = this.getWxAccessToken();
        JSONObject jsonObject1 = WechatUtil.getPhoneNumber(accessToken, phoneCode);
        log.info("getPhoneNumber:{}", jsonObject1.toJSONString());
        String errcode = jsonObject1.getString("errcode");
        String mobile = null;
        if ("0".equals(errcode)) {
            JSONObject phoneInfo = jsonObject1.getJSONObject("phone_info");
            mobile = phoneInfo.getString("phoneNumber");
        } else {
            throw new JeecgBootException("获取微信手机号失败");
        }
        Member member = memberHelp.getMember();
        Member recommend = memberService.getById(member.getRecommendId());
        String referrer1 = null;
        if (recommend != null) {
            referrer1 = recommend.getSourceMemberId();
        }
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("isAudit", 1);
        //检查蓝客帝是否有数据
        SourceMember sourceMember = sourceMemberService.getOne(new LambdaQueryWrapper<SourceMember>()
                .eq(SourceMember::getMobile, mobile)
                .eq(SourceMember::getUserType, 2) //用户注册
                .eq(SourceMember::getDelFlag, '0')
                .last("limit 1"));
        if (sourceMember == null) {
            //保存到蓝客帝用户表
            Map<String, Object> pmap = new HashMap<>();
            pmap.put("mobile", mobile);
            pmap.put("validCode", "6666");
            pmap.put("referrer1", referrer1);
            MsgResult msgResult = messageHelp.fxRegister(pmap);
            if (msgResult.getCode() == MsgResult.CODE_SUCCESS) {
                sourceMember = sourceMemberService.getOne(new LambdaQueryWrapper<SourceMember>()
                        .eq(SourceMember::getMobile, mobile)
                        .eq(SourceMember::getDelFlag, '0')
                        .eq(SourceMember::getUserType, 2) //用户注册
                        .last("limit 1"));
            } else {
                throw new JeecgBootException("绑定失败!同步用户错误");
            }
        }
        String sourceMemberId = sourceMember.getId();
        //分销商小程序注册,绑定蓝客帝用户ID
        Member newMember = new Member();
        newMember.setPhone(mobile);
        newMember.setSourceMemberId(sourceMemberId);
        newMember.setNickname(Optional.ofNullable(sourceMember.getName()).orElse("微信用户"));
        newMember.setAvatar(sourceMember.getAvatar());
        boolean res = memberService.update(newMember, new QueryWrapper<Member>().eq("id", member.getId()));
        if (res) {
            Member rec = memberService.getById(member.getRecommendId());
            Member resMember = memberService.getById(member.getId());
            resMember.setRecommend(rec);
            String token = JwtUtil.sign(resMember.getOpenid(), resMember.getOpenid());
            //设置token有效时间12小时
            redisUtil.set(resMember.getOpenid(), token, 60 * 60 * 12);
            resultMap.put("openid", resMember.getOpenid());
            resultMap.put("token", token);
            resultMap.put("member", resMember);
            return resultMap;
        } else {
            throw new JeecgBootException("绑定失败!");
        }
    }

    @Override
    public Member updateAvatar(String req) {
        Member member = memberHelp.getMember();
        JSONObject jsonObject = JSONObject.parseObject(req);
//        String openid = jsonObject.getString("openid");
        String avatar = jsonObject.getString("avatar");
        String nickname = jsonObject.getString("nickname");
        Member newMember = new Member();
        newMember.setAvatar(avatar);
        newMember.setNickname(nickname);
        memberService.update(newMember, new QueryWrapper<Member>().eq("id", member.getId()));
        return newMember;
    }

    @Override
    public Member updatePhone(String req) {
        Member member = memberHelp.getMember();
        JSONObject jsonObject = JSONObject.parseObject(req);
//        String openid = jsonObject.getString("openid");
        String mobile = jsonObject.getString("mobile");
        String validCode = jsonObject.getString("validCode");
        String validCodeId = jsonObject.getString("validCodeId");
        log.info("微信登录请求信息 ===> {}", req);
        Map<String, Object> vmap = new HashMap<>();
        vmap.put("mobile", mobile);
        vmap.put("validCode", validCode);
        vmap.put("validCodeId", validCodeId);
        if (StrUtil.isEmpty(mobile)) {
            throw new JeecgBootException("手机号不能为空");
        }
        if (member.getPhone().equals(mobile)) {
            throw new JeecgBootException("新手机号与当前相同");
        }
        Member memberEntity = memberService.getByPhone(mobile);
        if (memberEntity != null) {
            throw new JeecgBootException("手机号已被占用");
        }
        SourceMember sourceMember = sourceMemberService.getOne(new QueryWrapper<SourceMember>().eq("mobile", mobile).eq("del_flag", 0).eq("user_type", 2).last("limit 1"));
        if (sourceMember != null) {
            throw new JeecgBootException("手机号已被占用");
        }
        MsgResult result = messageHelp.validCode(vmap);
        if (result.getCode() != MsgResult.CODE_SUCCESS) {
            throw new JeecgBootException("验证码错误");
        }
        Member newMember = new Member();
        newMember.setPhone(mobile);
        boolean res = memberService.update(newMember, new QueryWrapper<Member>().eq("id", member.getId()));
        if (res) {
            SourceMember updateSource = new SourceMember();
            updateSource.setPhone(mobile);
            updateSource.setMobile(mobile);
            updateSource.setUsername(mobile);
            sourceMemberService.update(updateSource, new QueryWrapper<SourceMember>().eq("id", member.getSourceMemberId()));
        }
        return member;
    }

    @Override
    public Map<String, Object> loginPhone(String req) {
        JSONObject jsonObject = JSONObject.parseObject(req);
        String mobile = jsonObject.getString("mobile");
        //发布版本审核的指定账号
        Member member = memberService.getByPhone(mobile);
        String openid = member.getOpenid();
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("isAudit", 0);
        //检查用户
        Member memberDb = memberService.getByOpenid(openid);
        if (memberDb != null) {
            //保存登录信息
            String token = JwtUtil.sign(openid, openid);
            //设置token有效时间12小时
            redisUtil.set(openid, token, 60 * 60 * 12);
            resultMap.put("member", memberDb);
            resultMap.put("token", token);
        }
        return resultMap;
    }

    public String getWxAccessToken() {
        String token = (String) redisUtil.get("access_token");
        if (StringUtils.isEmpty(token)) {
            JSONObject jsonObject = WechatUtil.requestGetAccessToken();
            String accessToken = jsonObject.getString("access_token");
            String expires_in = jsonObject.getString("expires_in");
            if (StringUtils.isNotEmpty(accessToken)) {
                redisUtil.set("access_token", accessToken);
                long time = Long.parseLong(expires_in) - 10 * 60;
                redisUtil.expire("access_token", time);
                return accessToken;
            } else {
                return null;
            }
        } else {
            return token;
        }
    }
}
